package com.darkevil.jdspider.service

import com.darkevil.jdspider.entity.Category
import com.darkevil.jdspider.mapper.CategoryMapper
import com.darkevil.jdspider.utils.HttpClientUtil
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.json.JacksonJsonParser
import org.springframework.core.task.AsyncTaskExecutor
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor
import org.springframework.stereotype.Service

@Service
class CategoryService {
    @Autowired
    private lateinit var httpclient: HttpClientUtil
    private val logger = LoggerFactory.getLogger(CategoryService::class.java)
    @Autowired
    private lateinit var productService: ProductService
    @Autowired
    private lateinit var categoryMapper: CategoryMapper
    @Autowired
    private lateinit var taskExecutor: AsyncTaskExecutor

    /**
     * 获取分类
     */
    fun getCategory() {
        while (true) {
            val url = "https://dc.3.cn/category/get"
            val respStr = httpclient.sendHttpGet(url, charset = "gb2312")
            val jsonParser = JacksonJsonParser()
            val respMap = jsonParser.parseMap(respStr)
            val list: List<Map<String, Any>> = respMap["data"] as List<Map<String, Any>>
            var categoryList = arrayListOf<String>()
            list.forEach {
                val s = it["s"] as List<Map<String, Any>>?
                s?.forEach { subIt ->
                    categoryList.addAll(parseCategory(subIt))
                }
            }
            categoryList = categoryList.filter { it.contains("cat=") && !it.contains("&") } as ArrayList<String>
            categoryList.forEachIndexed { index, value ->
                val array = value.split("|")
                val categoryUrl = array[0].trim()
                val name = array[1].trim()
                val id = categoryUrl.substringAfter("=")
                val category = Category(id = id, url = if (categoryUrl.startsWith("http")) categoryUrl else "https://$categoryUrl", name = name)
                logger.debug(category.toString())
                val categoryTmp = categoryMapper.getCategoryById(id)
                if (categoryTmp == null) {
                    // 数据入库
                    categoryMapper.replace(category)
                } else if (System.currentTimeMillis() - categoryTmp.updateDate!!.time < 3 * 60 * 60 * 1000) {
                    logger.debug("${category.name}已处理，忽略")
                    return@forEachIndexed
                }
                // 启动异步方法
                productService.getProduct(category)
            }
            val threadPoolExecutor = (taskExecutor as ThreadPoolTaskExecutor).threadPoolExecutor
            while (true) {  // 判断是否所有任务都执行完成
                if (threadPoolExecutor.taskCount == threadPoolExecutor.completedTaskCount) {
                    logger.debug("处理完成")
                    break
                }
                Thread.sleep(5000)
            }
            // 一批任务执行完成后，强制gc，6小时后再次执行
            System.gc()
            Thread.sleep(6 * 60 * 60 * 1000)
        }
    }

    /**
     * 分类解析
     */
    private fun parseCategory(map: Map<String, Any>): MutableList<String> {
        val retList = arrayListOf<String>()
        var n = map["n"]
        if (n != null) {
            n = n as String
            if (n.contains("-") && !n.contains("com")) {
                n = "list.jd.com/list.html?cat=${n.replace("-", ",")}"
            }
            retList.add(n)
        }
        val s = map["s"] as List<Map<String, Any>>?
        s?.forEach {
            retList.addAll(parseCategory(it))
        }
        return retList
    }

    //    @Scheduled(cron = "*/5 * * * * ?")
    fun dbkeeper() {
        logger.info("保持数据库连接")
        categoryMapper.dbkeeper()
    }
}

//fun main(args: Array<String>) {
//    val s="list.jd.com/list.html?cat=1672,14227,14234&ev=1107%5F88514&sort=sort_totalsales15_desc&trans=1&JL=3_%E5%"
//    println(s.substringBefore("&"))
//}